import 'dart:ffi';

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '数据传递',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        splashColor: Colors.transparent,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _count = 0;

  void increment() {
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return CountProvider(
      count: _count,
      increment: increment,
      child: Scaffold(
        appBar: AppBar(
          title: Text('数据传递'),
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: increment,
        ),
        body: Column(
          children: [
            CountWidget(_count, increment),
            SizedBox(height: 12),
            CountWidget2(),
            SizedBox(height: 12),
            ScopeModelWidget(),
          ],
        ),
      ),
    );
  }
}

// 1.使用构造函数传递count参数：如果子节点过多一级级传很麻烦，而且中间的Widget可能不需要该参数，冗余
class CountWidget extends StatelessWidget {
  final int count;

  // 点击Clip的回调函数
  final VoidCallback incrementCount;

  CountWidget(this.count, this.incrementCount);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: ActionChip(
        label: Text('$count'),
        onPressed: incrementCount,
      ),
    );
  }
}

// 2.直接将数据创建给需要的Widget，不需要经过中间Widget，InheritedWidget
class CountProvider extends InheritedWidget {
  // 定义需要共享的数据
  final Widget child;
  final int count;
  final VoidCallback increment;

  CountProvider({this.child, this.count, this.increment}) : super(child: child);

  // 通过提供of命名构造方法，让外界初始化
  static CountProvider of(BuildContext context) =>
      context.dependOnInheritedWidgetOfExactType(aspect: CountProvider);

  // 当该组件状态改变，继承该组件的子组件是否需要重建
  @override
  bool updateShouldNotify(CountProvider oldWidget) {
    return oldWidget.count != count;
  }
}

class CountWidget2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final CountProvider countProvider = CountProvider.of(context);
    return Center(
      child: ActionChip(
        label: Text('${countProvider.count}'),
        onPressed: countProvider.increment,
      ),
    );
  }
}

// 3.使用scoped_model
// 定义数据共享的model
class CountModel extends Model {
  int _count = 0;

  int get count => _count;

  void incrementCount() {
    _count++;
    print('$_count');
    notifyListeners();
  }
}

class ScopeModelWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScopedModel(
      child: ScopeModelContent(),
      model: CountModel(),
    );
  }
}

class ScopeModelContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ScopedModelDescendant<CountModel>(
      builder: (ctx, child, countModel) => Center(
        child: ActionChip(
          label: Text('${countModel.count}'),
          onPressed: countModel.incrementCount,
        ),
      ),
      // 当数据发生改变，是否重新执行build方法构建视图
      // 类似于某些按钮组件，不需要改变状态的可以设置为false
      rebuildOnChange: true,
    );
  }
}
